package com.mrzhou.log.event;

import com.mrzhou.core.tool.constants.CloudConstant;
import com.mrzhou.core.tool.props.CloudProperties;
import com.mrzhou.log.constant.LogConstant;
import com.mrzhou.log.entity.LogApi;
import com.mrzhou.log.entity.LogError;
import com.mrzhou.log.feign.ILogFeignClient;
import com.mrzhou.log.support.GeneralHandlerLog;
import com.mrzhou.web.util.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestHeader;

import java.util.Map;
import java.util.UUID;

/**
 * @author qiang.zhou
 */
@Slf4j
public class ApiLogListener {

    @Autowired
    private CloudProperties cloudProperties;
    @Autowired
    private ILogFeignClient logFeignClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    private final RabbitTemplate.ConfirmCallback confirmCallback =  (correlationData, ack, cause) -> {
        if(!ack) {
            log.error("日志推送失败：correlationData: {},cause: {}", correlationData, cause);
        }
    };
    private final RabbitTemplate.ReturnCallback returnCallback = (message, replyCode, replyText, exchange, routingKey) -> {
        log.error("日志推送丢失: message: {}, exchange: {},routeKey: {},replyCode: {},replyText: {}", message, replyCode, replyText, exchange, routingKey);
    };

    /**
     * 异步监听器 将日志推送至RabbitMQ中，再处理
     * @param event
     */
    @Async
    @EventListener(ApiLogEvent.class)
    public void eventListener(ApiLogEvent event) {
        Map<String, Object> param = (Map) event.getSource();
        // 获取日志
        LogApi api = (LogApi) param.get(LogConstant.EVENT_LOG);
        GeneralHandlerLog.addOtherToLog(cloudProperties, api);

        // 推送至RabbitMQ
        // 构建回调返回的数据
        CorrelationData correlationData = new CorrelationData();
        // 生成消息ID
        correlationData.setId(UUID.randomUUID().toString());
        // 设置发送成功的回调方式
        rabbitTemplate.setConfirmCallback(confirmCallback);
        rabbitTemplate.setReturnCallback(returnCallback);
        rabbitTemplate.convertAndSend(LogConstant.LOG_EXCHANGE, LogConstant.LOG_QUEUE, api, correlationData);
    }

}
